using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using HybridCLR;
using UnityEngine;
using UnityEngine.Networking;

[Serializable]
public class DllDepend
{
    public string name;
    [HideInInspector] public byte[] bytes;
    public int length;
}

public class PreLoadDll : MonoBehaviour
{
    private Assembly hotUpdateAss;

    private string hotdll = "HotUpdate";
    private byte[] hotdllBytes;

    public List<DllDepend> dlls = new List<DllDepend>();

    public List<DllDepend> aotdlls = new List<DllDepend>();

    private void Start()
    {
        foreach (var dll in aotdlls)
        {
            Aot(dll.name, dll.bytes);
        }
        
        foreach (var dll in dlls)
        {
            Hot(dll.name, dll.bytes);
        }
        OnFinished();
    }

    private void OnFinished()
    {
        hotUpdateAss = Assembly.Load(hotdllBytes);
        if (hotUpdateAss != null)
        {
            Type type = hotUpdateAss.GetType("Hello");
            type.GetMethod("Run").Invoke(null, null);
        }
    }

    void Hot(string dllName, byte[] bytes)
    {
        if (dllName == hotdll)
        {
            hotdllBytes = bytes;
        }
        else
        {
            Debug.Log($"Hot:{dllName}");
            Assembly.Load(bytes);
        }
    }

    void Aot(string aotDllName, byte[] bytes)
    {
        Debug.Log($"Aot:{aotDllName}");
        // 加载assembly对应的dll，会自动为它hook。一旦aot泛型函数的native函数不存在，用解释器版本代码
        LoadImageErrorCode err = RuntimeApi.LoadMetadataForAOTAssembly(bytes, HomologousImageMode.Consistent);
        if (err == LoadImageErrorCode.OK)
            Debug.Log($"{aotDllName}: LoadMetadataForAOTAssembly:{aotDllName}. ret:{err}");
        else
            Debug.LogError($"{aotDllName}: LoadMetadataForAOTAssembly:{aotDllName}. ret:{err}");
    }
}